package com.ruoyi.web.controller.kaoyan;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.kaoyan.domain.EducationPartner;
import com.ruoyi.kaoyan.domain.EducationUnbindRecord;
import com.ruoyi.kaoyan.service.EducationPartnerService;
import com.ruoyi.kaoyan.service.EducationUnbindRecordService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.web.controller.kaoyan.vo.PartnerVo;
import com.ruoyi.web.controller.kaoyan.vo.UnbindVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 前台考研搭档类
 *
 * @author carpediem
 */
@Validated
@Api(tags = "前台考研搭档", value = "前台考研搭档")
@RequestMapping("/v2/partner")
@RestController
public class PartnerApi extends BaseController {

    @Autowired
    private EducationPartnerService partnerService;
    @Autowired
    private ISysUserService userService;

    @Autowired
    private EducationUnbindRecordService unbindRecordService;

    @ApiOperation("搭档申请")
    @PostMapping("/apply")
    public AjaxResult apply(@NotNull(message = "用户id不能为空") Long userId) {
        Long id = SecurityUtils.getUserId();
        if (userId.equals(id)) {
            return AjaxResult.warn("不能申请自己成为搭档");
        }
        LambdaQueryWrapper<EducationPartner> eq = new LambdaQueryWrapper<EducationPartner>()
                .eq(EducationPartner::getMatchFlag, 1)
                .and(e -> e.eq(EducationPartner::getUserId, id)
                        .or(f -> f.eq(EducationPartner::getApplyUserId, id))
                        .or(r -> r.eq(EducationPartner::getUserId, userId))
                        .or(q -> q.eq(EducationPartner::getApplyUserId, userId)));
        EducationPartner serviceOne = partnerService.getOne(eq);
        if (!StringUtils.checkObjAllFieldsIsNull(serviceOne)) {
            return AjaxResult.warn("已有搭档或对方已有搭档");
        }
        LambdaQueryWrapper<EducationPartner> wrapper = new LambdaQueryWrapper<EducationPartner>()
                .eq(EducationPartner::getApplyUserId, userId)
                .eq(StringUtils.isNotNull(id), EducationPartner::getUserId, id);
        List<EducationPartner> list = partnerService.list(wrapper);
        if (list.size() > 0){
            return AjaxResult.warn("等待对方处理，请勿重复申请");
        }
        SysUser user = userService.selectUserById(userId);
        if (StringUtils.isNull(user)) {
            return AjaxResult.warn("用户不存在");
        }
        EducationPartner partner = EducationPartner.builder()
                .applyUserId(userId)
                .userId(id)
                .build();
        boolean save = partnerService.save(partner);
        return toAjax(save);
    }

    @ApiOperation("搭档列表（我的申请、我收到的申请）")
    @PostMapping("/list")
    public AjaxResult list(Long userId) {
        LambdaQueryWrapper<EducationPartner> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotNull(userId)) {
            queryWrapper.eq(EducationPartner::getUserId, userId);
        } else {
            Long userId2 = SecurityUtils.getUserId();
            queryWrapper.eq(true, EducationPartner::getApplyUserId, userId2);
        }
        Page<EducationPartner> page = partnerService.page(startPagePlus(), queryWrapper);
        List<EducationPartner> partnerList = page.getRecords();
        Set<Long> userIdSet = partnerList.stream().map(EducationPartner::getUserId).collect(Collectors.toSet());
        Set<Long> applyUserIdSet = partnerList.stream().map(EducationPartner::getApplyUserId).collect(Collectors.toSet());
        List<SysUser> list = userService.list(new LambdaQueryWrapper<SysUser>().in(StringUtils.isNotEmpty(userIdSet), SysUser::getUserId, userIdSet));
        List<SysUser> userList = userService.list(new LambdaQueryWrapper<SysUser>().in(StringUtils.isNotEmpty(applyUserIdSet), SysUser::getUserId, applyUserIdSet));
        Map<Long, String> userMap = list.stream().collect(Collectors.toMap(SysUser::getUserId, SysUser::getUserName));
        Map<Long, String> user2Map = userList.stream().collect(Collectors.toMap(SysUser::getUserId, SysUser::getUserName));
        List<PartnerVo> partnerVoList = partnerList.stream().map(e -> new PartnerVo(e, userMap, user2Map)).collect(Collectors.toList());
        return AjaxResult.ok().page(page, partnerVoList).build();
    }

    @ApiOperation("我的搭档")
    @PostMapping("/partner")
    public AjaxResult partner() {
        Long userId = SecurityUtils.getUserId();
        LambdaQueryWrapper<EducationPartner> eq = new LambdaQueryWrapper<EducationPartner>()
                .eq(EducationPartner::getMatchFlag, 1)
                .and(e -> e.eq(EducationPartner::getUserId, userId)
                        .or(r -> r.eq(EducationPartner::getApplyUserId, userId)));
        EducationPartner partner = partnerService.getOne(eq);
        SysUser user = new SysUser();
        if (StringUtils.checkObjAllFieldsIsNull(partner)) {
            return AjaxResult.ok().proPut("partner", user).build();
        }
        Long userId1 = partner.getUserId();
        Long applyUserId = partner.getApplyUserId();
        if (userId.equals(userId1)) {
            user = userService.selectUserById(applyUserId);
        } else if (userId.equals(applyUserId)) {
            user = userService.selectUserById(userId1);
        }
        return AjaxResult.ok().proPut("partner", user).build();
    }

    @ApiOperation("通过申请")
    @PostMapping("/agree")
    public AjaxResult agree(Long id) {
        Long admin = SecurityUtils.getUserId();
        if (StringUtils.isNull(admin)){
            return AjaxResult.error("会话过期，请重新登录");
        }
        EducationPartner partner = partnerService.getById(id);
        //邀请者
        Long userId = partner.getUserId();
        List<EducationPartner> partnerList = partnerService.list(new LambdaQueryWrapper<EducationPartner>()
                .eq(EducationPartner::getMatchFlag, 1)
                .and(e -> e.eq(EducationPartner::getUserId, userId)
                        .or(r -> r.eq(EducationPartner::getApplyUserId, userId))));
        if (partnerList.size() > 0){
            return AjaxResult.warn("该用户已有拍档");
        }
        partner.setMatchFlag(1);
        boolean update = partnerService.updateById(partner);
        //批量拒绝其他邀请者
        if (update){
            List<EducationPartner> list = partnerService.list(new LambdaQueryWrapper<EducationPartner>()
                    .eq(EducationPartner::getApplyUserId, admin)
                    .isNull(EducationPartner::getMatchFlag));
            list.forEach(e -> e.setMatchFlag(0));
            if (StringUtils.isEmpty(list)){
                return toAjax(true);
            }
            boolean b = partnerService.updateBatchById(list);
            if (!b){
                return AjaxResult.warn("批量拒绝失败");
            }
        }
        return toAjax(update);
    }

    @ApiOperation("拒绝申请")
    @PostMapping("/reject")
    public AjaxResult reject(Long id) {
        EducationPartner partner = partnerService.getById(id);
        partner.setMatchFlag(0);
        boolean update = partnerService.updateById(partner);
        return toAjax(update);
    }

    @ApiOperation("搭档申请结果通知列表")
    @PostMapping("/resultList")
    public AjaxResult resultList() {
        Long userId = SecurityUtils.getUserId();
        LambdaQueryWrapper<EducationPartner> queryWrapper = new LambdaQueryWrapper<EducationPartner>()
                .eq(StringUtils.isNotNull(userId), EducationPartner::getUserId, userId);
        Page<EducationPartner> page = partnerService.page(startPagePlus(), queryWrapper);
        List<EducationPartner> partnerList = page.getRecords();
        Set<Long> applyUserIdSet = partnerList.stream().map(EducationPartner::getApplyUserId).collect(Collectors.toSet());
        List<SysUser> userList = userService.list(new LambdaQueryWrapper<SysUser>().in(StringUtils.isNotEmpty(applyUserIdSet), SysUser::getUserId, applyUserIdSet));
        Map<Long, String> user2Map = userList.stream().collect(Collectors.toMap(SysUser::getUserId, SysUser::getUserName));
        List<PartnerVo> partnerVoList = partnerList.stream().map(e -> new PartnerVo(e, user2Map)).filter(e ->! Objects.equals(e.getMatchFlag(), "null")).collect(Collectors.toList());
        return AjaxResult.ok().page(page, partnerVoList).build();
    }

    @ApiOperation("搭档解绑申请")
    @PostMapping("/unbinding")
    public AjaxResult unbinding(@NotNull(message = "申请解绑的用户id不能为空") Long userId, String applyMessage){
        Long userId1 = SecurityUtils.getUserId();
        if (StringUtils.isNull(userId1)){
            return AjaxResult.warn("会话过期，请重新登录");
        }
        EducationUnbindRecord unbindRecord = EducationUnbindRecord.builder()
                .userId(userId1)
                .partnerUserId(userId)
                .applyMessage(applyMessage)
                .build();
        boolean save = unbindRecordService.save(unbindRecord);
        return toAjax(save);
    }

    @ApiOperation("搭档解绑通知列表")
    @PostMapping("/unbindList")
    public AjaxResult unbindList() {
        Long userId = SecurityUtils.getUserId();
        if (StringUtils.isNull(userId)){
            return AjaxResult.warn("会话过期，请重新登录");
        }
        LambdaQueryWrapper<EducationUnbindRecord> queryWrapper = new LambdaQueryWrapper<EducationUnbindRecord>()
                .eq(EducationUnbindRecord::getPartnerUserId, userId)
                .or()
                .eq(EducationUnbindRecord::getUserId ,userId);
        Page<EducationUnbindRecord> page = unbindRecordService.page(startPagePlus(), queryWrapper);
        List<EducationUnbindRecord> unbindList = page.getRecords();
        Set<Long> userIdSet = unbindList.stream().map(EducationUnbindRecord::getUserId).collect(Collectors.toSet());
        Set<Long> partnerIdSet = unbindList.stream().map(EducationUnbindRecord::getPartnerUserId).collect(Collectors.toSet());
        List<SysUser> userList = userService.list(new LambdaQueryWrapper<SysUser>().in(StringUtils.isNotEmpty(userIdSet), SysUser::getUserId, userIdSet));
        List<SysUser> partnerList = userService.list(new LambdaQueryWrapper<SysUser>().in(StringUtils.isNotEmpty(partnerIdSet), SysUser::getUserId, userIdSet));
        Map<Long, String> user2Map = userList.stream().collect(Collectors.toMap(SysUser::getUserId, SysUser::getUserName));
        Map<Long, String> partnerMap = partnerList.stream().collect(Collectors.toMap(SysUser::getUserId, SysUser::getUserName));
        List<UnbindVo> unbindVoList = unbindList.stream().map(e -> new UnbindVo(e, user2Map, partnerMap)).collect(Collectors.toList());
        return AjaxResult.ok().page(page, unbindVoList).build();
    }

    @ApiOperation("同意解绑")
    @PostMapping("/agreeUnbind")
    public AjaxResult agreeUnbind(@NotNull(message = "解绑申请id不能为空") Long id){
        EducationUnbindRecord unbindRecord = unbindRecordService.getById(id);
        if (StringUtils.checkObjAllFieldsIsNull(unbindRecord)){
            return AjaxResult.warn("该条解绑记录不存在");
        }
        unbindRecord.setBindFlag(1);
        boolean update = unbindRecordService.updateById(unbindRecord);
        if (update){
            LambdaQueryWrapper<EducationPartner> queryWrapper = new LambdaQueryWrapper<EducationPartner>()
                    .eq(EducationPartner::getMatchFlag, 1)
                    .and(e -> e.eq(EducationPartner::getUserId, unbindRecord.getUserId())
                            .or(f -> f.eq(EducationPartner::getUserId, unbindRecord.getPartnerUserId()))).last("limit 1");
            EducationPartner partner = partnerService.getOne(queryWrapper);
            LambdaUpdateChainWrapper<EducationPartner> set = partnerService.lambdaUpdate().set(EducationPartner::getMatchFlag, null);
            boolean b = partnerService.update(partner, set.getWrapper());
            if (!b){
                return AjaxResult.error("解绑失败");
            }
        }
        return toAjax(update);
    }

    @ApiOperation("拒绝解绑")
    @PostMapping("/rejectUnbind")
    public AjaxResult rejectUnbind(@NotNull(message = "解绑申请id不能为空") Long id, String rejectMessage){
        EducationUnbindRecord unbindRecord = unbindRecordService.getById(id);
        if (StringUtils.checkObjAllFieldsIsNull(unbindRecord)){
            return AjaxResult.warn("该条解绑记录不存在");
        }
        unbindRecord.setBindFlag(0);
        unbindRecord.setComment(rejectMessage);
        boolean update = unbindRecordService.updateById(unbindRecord);
        return toAjax(update);
    }

}
